package com.itheima.demo;

import com.alibaba.fastjson.JSON;
import com.itheima.pojo.User;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 实现  document 的 搜索search
 * @作者 itcast
 * @创建日期 2021/4/2 8:54
 **/
public class EsDemo03 {

    /**
     * 查询全部
     */
    @Test
    public void matchAll() throws IOException {
//// 1. 创建 SearchRequest请求
        SearchRequest request = new SearchRequest("user");
//        SearchSourceBuilder 来封装所有的请求参数
        SearchSourceBuilder builder = new SearchSourceBuilder();
//        builder.query() 设置查询条件
          builder.query(QueryBuilders.matchAllQuery());
//        通过工具类封装各种查询类型  QueryBuilders
//        builder.sort() 设置排序条件
//        builder.from() 设置分页条件
//        builder.size()
//        builder.highlight()  高亮条件
//        builder.aggregations() 聚合条件
        request.source(builder);
//// 2. 客户端执行search方法(SearchRequest请求)
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
//// 3. 解析响应结果  SearchResponse对象
        // 查询结果
        SearchHits hitsResult = searchResponse.getHits();
        System.out.println("查询到结果总数量: " + hitsResult.getTotalHits().value);
//        response.getHits
        SearchHit[] hitsDoc = hitsResult.getHits();
//                遍历文档列表
        for (SearchHit searchHit : hitsDoc) {
            //        获取文档中的source内容
//                封装成User对象
            String userJson = searchHit.getSourceAsString();
            User user = JSON.parseObject(userJson, User.class);
            System.out.println(user);
        }
    }
    @Test
    public void matchQuery() throws IOException {
        int page = 2;
        int pageSize = 2;
        //  note:  javaee唱歌
        // 创建查询条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
//        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("note", "javaee唱歌");
//        matchQueryBuilder.operator(Operator.AND)
        builder.query(QueryBuilders.matchQuery("note","同学"));
        // 排序字段    升序降序
        builder.sort("age", SortOrder.DESC);  // 先按照年龄降序排序
        builder.sort("gender", SortOrder.ASC); // 再按照性别升序排序
        builder.from((page - 1)*pageSize); // 设置分页
        builder.size(pageSize);
        printResult(builder);
    }
    /**
     * 查询 18 ~ 28 之间的所有同学
     * @throws IOException
     */
    @Test
    public void rangeQuery() throws IOException {
        // 创建查询条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.rangeQuery("age").gte(18).lte(28));
        printResult(builder);
    }

    /**
     * 分词查询  note字段  包含 同学   must
     * 范围查询  age字段  18 ~ 28     must
     * 词条查询  gender字段   0       must
     */
    @Test
    public void boolQuery() throws IOException {
        // 创建查询条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 创建 布尔查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//         * 分词查询  note字段  包含 同学   must
        boolQueryBuilder.must(QueryBuilders.matchQuery("note","同学"));
//                * 范围查询  age字段  18 ~ 28     must
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(18).lte(28));
//                * 词条查询  gender字段   0       must
        boolQueryBuilder.filter(QueryBuilders.termQuery("gender","0"));
        builder.query(boolQueryBuilder);
        printResult(builder);
    }




    /**
     * 抽取解析结果代码
     * @param builder
     * @throws IOException
     */
    public void printResult(SearchSourceBuilder builder) throws IOException {
        //// 1. 创建 SearchRequest请求
        SearchRequest request = new SearchRequest("user");
        request.source(builder);
//// 2. 客户端执行search方法(SearchRequest请求)
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
//// 3. 解析响应结果  SearchResponse对象
        // 查询结果
        SearchHits hitsResult = searchResponse.getHits();
        System.out.println("查询到结果总数量: " + hitsResult.getTotalHits().value);
//        response.getHits
        SearchHit[] hitsDoc = hitsResult.getHits();
//                遍历文档列表
        for (SearchHit searchHit : hitsDoc) {
            System.out.println("文档得分: " + searchHit.getScore());
            //        获取文档中的source内容
//                封装成User对象
            String userJson = searchHit.getSourceAsString();
            User user = JSON.parseObject(userJson, User.class);
            System.out.println(user);
        }
    }


    RestHighLevelClient client;

    /**
     * 初始化es 客户端
     */
    @Before
    public void init(){
        client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("192.168.200.130", 9200, "http")));


    }


    /**
     * 关闭es 客户端
     */
    @After
    public void close(){
        try {
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
